package IEFYP.JunkCallFiltering;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.text.format.Time;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsoluteLayout;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.SimpleAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import IEFYP.JunkCallFiltering.MyAdapter;
//import IEFYP.JunkCallFiltering.CallInfo;


/**problem:		1. layout : need to change to relative layout ( Since no problem)
 * 				2. Report Incomming call date; // Not connect to server 
 * 				3. Detect Network Connection //** HANDLED BY SETTING TIMEOUT
 * 				4. Problem of date of the the call in history // solved by changing the type
 * 				5. Secure reporting
 * 				6. Report information <-- except report time 
 * 				7. Server Handling for two params: incoming time and duration
 * 				8. Service for auto-late reporting when no internet service.
 * 				*9. performance about large number of data!!!!<!!!<!!<!<!<
 * 				*10. Auto-select the first Item in ListView done 
 * 				*11. Remove from the history!!! done
 * 				*12. Add to userlist done
 * 				13. if FromPrompt, The current page cannot be this activity. 
 * @author KOLee
 *
 */

@SuppressWarnings("deprecation")
public class ReportJunkCall extends Activity {
	private final String Tag= "ReportJunkCall";
	public final static String ServerIp= "192.168.64.65";
    //ServerIp = "137.189.206.142";
	private ListView reportlist;
	private Spinner spn_type;
	private Spinner spn_feature;
	private MyAdapter listItemAdapter ;
	private Button b_report;
	private String btype,callchar,callno,datetime ;
	private boolean FromPrompt = false;
	
	List<CallInfo> historyCallList;	
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        
        setContentView(R.layout.report);
        

        
        btype=new String();
        callchar=new String();
        callno="null";
        
        
        Bundle bundle = this.getIntent().getExtras();
        FromPrompt = bundle.getBoolean("FromPrompt");
        
        
        findView();
        setListView();
        setSpinner();
        setOnClickListener();
        
    }
    
    private void setOnClickListener(){
    	b_report.setOnClickListener(reportJunkCall);  	
    	
      }

/*    
    public static int lookupHost(String hostname) {
        InetAddress inetAddress;
        try {
            inetAddress = InetAddress.getByName(hostname);
        } catch (UnknownHostException e) {
            return -1;
        }
        byte[] addrBytes;
        int addr;
        addrBytes = inetAddress.getAddress();
        addr = ((addrBytes[3] & 0xff) << 24)
                | ((addrBytes[2] & 0xff) << 16)
                | ((addrBytes[1] & 0xff) << 8)
                |  (addrBytes[0] & 0xff);
        return addr;
    }
*/
    
    public static DefaultHttpClient setupHttpClient(){
    	
    		//Scheme https = new Scheme("https",SSLSocketFactory.getSocketFactory(), 443); for https
    		Scheme http = new Scheme("http",new PlainSocketFactory(), 80); 
			 
			SchemeRegistry schemeRegistry = new SchemeRegistry();
			schemeRegistry.register(http);
			
		    BasicHttpParams httpParams = new BasicHttpParams();

		    HttpConnectionParams.setConnectionTimeout(httpParams, 1000);//Set the timeout in milliseconds until a connection is established.
		    HttpConnectionParams.setSoTimeout(httpParams, 5000); //timeout for waiting for data.
		    ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(
		            httpParams,schemeRegistry );
		   //this.httpClient = new DefaultHttpClient(cm, httpParams);
   		 DefaultHttpClient client = new DefaultHttpClient(cm,httpParams);
   		return client;
    }
      
    private OnClickListener reportJunkCall = new OnClickListener(){
   	 public void onClick(View v){
  
		   		 if(callno!="null"){
		   			 DefaultHttpClient client =  setupHttpClient();
		   			 
			    //	String url = "http://192.168.172.130/collectcalls.php?callno="+callno+"&btype=\""+btype+"\"&callchar=\""+callchar+"\"&datetime="+time.format2445();
				//	HttpGet request = new HttpGet(url);
			    	String url = "http://"+ServerIp+"/collectcalls.php";
			    	HttpPost request = new HttpPost(url);
			    	
				    	try{
				    		String Duration="Fail";     //two information for reporting
				    		Time ReportTime = new Time();
				    		ReportTime.setToNow();
				    		
				    		for(CallInfo call : historyCallList){  // Cancel duplicated number 
								if(call.Number.contentEquals(callno)){  //Numbers are in descending order
									Duration = call.Duration;									
									break;
								}
							}
				    		
				    		//String url = "http://192.168.172.130/collectcalls.php?callno="+callno+"&btype="+btype+"&callchar="+callchar+"&datetime="+time.format2445();
				    		List<NameValuePair> postValues = new ArrayList<NameValuePair>();
				    		postValues.add(new BasicNameValuePair("callno",callno));
				    		postValues.add(new BasicNameValuePair("btype",btype));
				    		postValues.add(new BasicNameValuePair("callchar",callchar));
				    	//	postValues.add(new BasicNameValuePair("datetime",ReportTime.format2445()));//report date
				    		postValues.add(new BasicNameValuePair("datetime",datetime)); //incure date

				    	
				    		request.setEntity(new UrlEncodedFormEntity(postValues));
				    		//Toast.makeText(ReportJunkCall.this,"Successfully reported!!",Toast.LENGTH_SHORT).show();
				    		HttpResponse response = client.execute(request);
				   			if(response.getStatusLine().getStatusCode()==200){
				   				Toast.makeText(ReportJunkCall.this,
				   						"Successfully reported!!\n"
				   						+"Duration:"+Duration
				   						+"\nIncomingTime:"+datetime,
				   						Toast.LENGTH_SHORT).show(); 
				   				
				   				//Delete call log of the reported call
				   				getContentResolver().delete(android.provider.CallLog.Calls.CONTENT_URI,android.provider.CallLog.Calls.NUMBER+"='"+callno+"'" , null);
				   				
				   				
				   				DBhelper b_helper = new DBhelper(ReportJunkCall.this, "blacklist");
				   				DBhelper u_helper = new DBhelper(ReportJunkCall.this, "userlist");
				   				b_helper.OpenDB();
				   				u_helper.OpenDB();
				   				boolean b_NotExisted = b_helper.findNumber(callno,false).equals("NULL"); 
				   				boolean u_NotExisted = u_helper.findNumber(callno,false).equals("NULL");
				   				b_helper.close();
				   				if(b_NotExisted && u_NotExisted){			   			
				   				u_helper.insert(callno,"1", 1);
				   				u_helper.close();
				   				}
				
						   		 if(FromPrompt){
						   			 finish();
						   		 }else{
						   			setListView();
						   		 }
				   			}
				   			
				    		
				   			//	Toast.makeText(ReportJunkCall.this,"No Internet Service!!",Toast.LENGTH_SHORT).show(); 
				   			
				   		 }catch (Exception e){
				   			 
				   			 //Toast.makeText(ReportJunkCall.this,e.toString(),200).show(); 
				   			 Log.v(Tag,e.getMessage());
				   			 if(isOnline(ReportJunkCall.this)){
				   				Toast.makeText(ReportJunkCall.this,"Server is unavailable!",200).show(); 
				   				Log.v(Tag," server unavailable! ");
				   				// Try to send again every 3 hours;
				   				
				   			 }else{
				   				Log.v(Tag," No Internet service! ");
				   				Toast.makeText(ReportJunkCall.this,"No Internet service!",200).show(); 
				   				//Try to send until the Internet service is available
				   			 }
				   			 
					   		 if(FromPrompt){
					   			 finish();
					   		 }
				   		 }
				   		 
			   	 }else{
			   		Toast.makeText(ReportJunkCall.this,"Please select one Call Number!",Toast.LENGTH_SHORT).show(); 
			   	 }
		   		 
		   		 


   	 }

   };
   
   
   public static boolean isOnline(Context context) {
	   boolean result;
	   ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
	   if(cm.getActiveNetworkInfo()!=null){
		   result = cm.getActiveNetworkInfo().isConnectedOrConnecting();
	   }else{
		   result = false;
	   }
	   return result;

	  }
   
   
    
    private void findView(){
    	reportlist = (ListView) findViewById(R.id.reportlist);
    	spn_type = (Spinner) findViewById(R.id.rep_spn_type);
    	spn_feature = (Spinner) findViewById(R.id.rep_spn_feature);
    	b_report = (Button) findViewById(R.id.b_report);
    }
    
    private void setListView(){
    	historyCallList = new ArrayList<CallInfo>();
    	/************Get DateFrom history**************************************************/
    	// Querying for a cursor is like querying for any SQL-Database 
    	Cursor c = getContentResolver().query(
				android.provider.CallLog.Calls.CONTENT_URI,
				null,null,null,	//null,android.provider.CallLog.Calls.CACHED_NAME+"=\"\"", null,  
				android.provider.CallLog.Calls.DATE+" DESC,"+android.provider.CallLog.Calls.NUMBER+ " DESC"); //first by Date,Second by Number
    	
    	startManagingCursor(c); // auto re-querying
		
		//CACHED_NAME,CACHED_NUMBER_LABEL,CACHED_NUMBER_TYPE,DATE,DURATION ,NEW,NUMBER,TYPE
		// Retrieve the column-indixes of phoneNumber, date and calltype
		
    	int cachedName = c.getColumnIndex(
				android.provider.CallLog.Calls.CACHED_NAME);
		int numberColumn = c.getColumnIndex(
				android.provider.CallLog.Calls.NUMBER);
		int dateColumn = c.getColumnIndex(
				android.provider.CallLog.Calls.DATE);
		// type can be: Incoming, Outgoing or Missed
		int typeColumn = c.getColumnIndex(
				android.provider.CallLog.Calls.TYPE);
		
		int durationColumn = c.getColumnIndex(
				android.provider.CallLog.Calls.DURATION);
		
		//	int test = 0;
		// Loop through all entries the cursor provides to us.
		if(c.moveToFirst()){
			do{
				//Time time = new Time();
				if(c.isNull(cachedName)   // GET NO NAME(IN THE CONTACTLIST) AND NOT OUTGOING CALL
				&&c.getInt(typeColumn)!= android.provider.CallLog.Calls.OUTGOING_TYPE
				&&!c.getString(numberColumn).equals("-2")
				)
				{
					
					CallInfo calls = new CallInfo();
				//	int test2 = c.getInt(test);
					
					String callerPhoneNumber = c.getString(numberColumn);
					long callDate = c.getLong(dateColumn); //Must to be long, otherwise the date time is not correct!!!!XD
					int callType = c.getInt(typeColumn);
					int callDuration = c.getInt(durationColumn);
					//long created = c.getLong(dateColumn);
					// Date date = new Date(callDate);
				
					//String dateString = Integer.toString(callDate);
					MyDateTime date = new MyDateTime();
					
					/*	Time date = new Time();		
					    date.set(callDate);*/
				//	String dateString = DateFormat.getDateTimeInstance().format(callDate);// DateFormat makes the program very slow
				  	String dateString =date.toMyDateTime(callDate); //***Very Slow!!!
				  	// String dateString = date.format2445();  //The fastest
					calls.Number = callerPhoneNumber;
					calls.DateTime =  dateString; //Integer.toString(callDate);Integer.toString(test++);//
					calls.Duration = Integer.toString(callDuration);
					
					switch(callType){
						case android.provider.CallLog.Calls.INCOMING_TYPE:
							calls.Type = "Incomming";
							break;
						case android.provider.CallLog.Calls.MISSED_TYPE:
							calls.Type = "Missed";
							break;
						case android.provider.CallLog.Calls.OUTGOING_TYPE:
							calls.Type = "Outgoing";
							break;
					}
					
					//historyCallList.add(calls);
					// Convert the unix-timestamp to a readable datestring
					//String dateString = DateUtils.dateString(callDate).toString();
					
					
					boolean updated = false;
						if(historyCallList.isEmpty()){
							historyCallList.add(calls);
						}else{
							for(CallInfo call : historyCallList){  // Cancel duplicated nubmer 
								if(call.Number.contentEquals(calls.Number)){  //Numbers are in descending order
									call.DateTime = calls.DateTime;
									call.Duration = calls.Duration;
									call.Type = calls.Type;
									updated = true;
									break;
								}
							}						
							if(updated == false){
								historyCallList.add(calls);
							}						
						}					 
				}
			}while(c.moveToNext()); 		
		}


		if(!historyCallList.isEmpty()){
			List<Map<String, String>> ListItem = new ArrayList<Map<String,String>>();
	    	
			for(int i=0; i<historyCallList.size();i++){
        		
        		HashMap<String,String> map = new HashMap<String, String>();
        		map.put("No.", historyCallList.get(i).Number);
        		map.put("Type", historyCallList.get(i).DateTime);
        		ListItem.add(map);
        	}
    	    	
    	//Log.e(this.toString(), "error: 1");
    	/****************************************************************************
      	List<Map<String, String>> ListItem = new ArrayList<Map<String,String>>();
      	for(int i=0; i<10;i++){
    		String j= Integer.toString(i);
    		HashMap<String,String> map = new HashMap<String, String>();
    		map.put("No.","2345678"+j);
    		map.put("Type","Company"+j);
    		ListItem.add(map);
    	}
    	******************************************************************************/
    	//Log.e(this.toString(), "error:2");
			listItemAdapter = new MyAdapter(this,ListItem,
					R.layout.blacklistcontent,
					new String[]{"No.","Type"},
					new int[]{R.id.callno,R.id.type}
				);
 	   	//Log.e(this.toString(), "error:3 ");
			if(FromPrompt){
				listItemAdapter.map.put(0, true);
				callno = historyCallList.get(0).Number;
				datetime = historyCallList.get(0).DateTime;
				Toast.makeText(this, "You selected "+callno, Toast.LENGTH_LONG).show();
				
			}
			reportlist.setAdapter(listItemAdapter);
    	
			reportlist.setOnItemClickListener(new OnItemClickListener() {
			
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
            	 listItemAdapter.refreshCheckBox(position);
            	 reportlist.setAdapter(listItemAdapter);
                 reportlist.setSelection(position);
             	 
                 CheckBox checkBox = (CheckBox) view.findViewById(R.id.b_select); 
                 checkBox.toggle();
                 listItemAdapter.map.put(position, checkBox.isChecked());
                                     
                 // TODO Auto-generated method stub 
                 AbsoluteLayout lr=(AbsoluteLayout)view;
                 if(checkBox.isChecked()){
                	 TextView mText=(TextView)lr.getChildAt(1);
                	 TextView mDatetime=(TextView)lr.getChildAt(0);
                	 callno = mText.getText().toString();
                	 datetime = mDatetime.getText().toString();
                	 Toast.makeText(ReportJunkCall.this, "You selected Item NO."+ position+"\nCall No.:"+mText.getText().toString(),//+"\n"+cb.toString(),
                			 Toast.LENGTH_SHORT).show();  
                 }else{
                	 callno="null";
                 }
             }
             
			});

		}else{
			List<Map<String, String>> List = new ArrayList<Map<String,String>>();
			HashMap<String,String> mapping = new HashMap<String, String>();
			mapping.put("Notice","No Records");
			List.add(mapping);
			SimpleAdapter  adapter = new SimpleAdapter(this,List,
					R.layout.norecords,
					new String[]{"Notice"},
					new int[]{R.id.no_records});
			reportlist.setAdapter(adapter);
		}
  
    }
      
    private void setSpinner(){
        Resources res=getBaseContext().getResources();
        String[] types = res.getStringArray(R.array.types);
        String[] charateristics = res.getStringArray(R.array.charateristics);
    	
    	
    	ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,types);
    	adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    	spn_type.setAdapter(adapter);
    	
    	spn_type.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){
            @SuppressWarnings("rawtypes")
			public void onItemSelected(AdapterView adapterView, View view, int position, long id){
               
            	btype = adapterView.getSelectedItem().toString();
            //	Toast.makeText(ReportJunkCall.this, "You selected "+btype, Toast.LENGTH_SHORT).show();
            }
            @SuppressWarnings("rawtypes")
			public void onNothingSelected(AdapterView arg0) {
                Toast.makeText(ReportJunkCall.this, "No Selection", Toast.LENGTH_SHORT).show();
            }
           
        });
         
    	
    	adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,charateristics);
    	adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    	spn_feature.setAdapter(adapter);
    	
    	spn_feature.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){
            @SuppressWarnings("rawtypes")
			public void onItemSelected(AdapterView adapterView, View view, int position, long id){
               
            	 callchar = adapterView.getSelectedItem().toString();
            	// Toast.makeText(ReportJunkCall.this, "You selected "+callchar, Toast.LENGTH_SHORT).show();
            }
            @SuppressWarnings("rawtypes")
			public void onNothingSelected(AdapterView arg0) {
                Toast.makeText(ReportJunkCall.this, "No Selection", Toast.LENGTH_SHORT).show();
            }           
        });
             
    }
    
   static public class MyDateTime{
    	public String currentTime;
    	public MyDateTime(){
    		java.util.Date dt = new java.util.Date();
    		java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		currentTime = sdf.format(dt);
    	}
    	public String toMyDateTime(long datetime){
    		java.util.Date dt = new java.util.Date();
    		dt.setTime(datetime);
    		java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		String Time = sdf.format(dt);
    		return Time;
    	}
    	
    }
    
    public class CallInfo {
    	
    	public String Number;
    	public String Type;
    	public String BusinessType;
    	public String Characteristic;
    	public String DateTime;
    	public String Duration;
    	//CACHED_NAME,CACHED_NUMBER_LABEL,CACHED_NUMBER_TYPE,DATE,DURATION ,NEW,NUMBER,TYPE
    	
    	
    	public CallInfo(){
    		Number="null";
    		Type="null";
    		Characteristic="null";
    		DateTime="null";
    		Duration="null";
    	}
    }
}